<?php

namespace core;

class Response
{
    // 当前状态码（默认200）
    protected $statusCode = 200;
    // 是否已发送响应（防止重复输出）
    protected $sent = false;

    // 响应头 
    protected $headers = "";

    /**
     * 设置状态码
     * @param int $code HTTP 状态码（如404、500）
     * @param $this 支持链式调用
     */
    public function status(int $code): self
    {
        $this->statusCode = $code;
        // 如果未发送响应，则更新状态码
        if (!$this->sent) {
            $this->headers .= "HTTP/1.1 {$code} OK\r\n";
        }

        return $this;
    }

    /**
     * 设置响应头
     * @param string $key 头部名称（如'Content-Type'）
     * @param string $value 头部值
     * @param bool $replace 是否覆盖已有同名头
     * @return $this    支持链式调用
     */
    public function header(string $key, string $value, bool $replace = true): self
    {
        if (!$this->sent) {
            $this->headers .= "$key: $value\r\n";
        }

        return $this;
    }

    /**
     * 重定向到指定URL
     * @param string $url   目标URL
     * @param int $code     重定向状态码（301 永久/302 临时， 默认302）
     * @return void         直接终止脚本
     */
    public function redirect(string $url, int $code = 302)
    {
        $this->status($code);
        $this->header('Location', $url);
        $this->send();  //确保头信息发送
        exit;
    }

    /**
     * 返回JSON数据（自动处理编码和状态码）
     * @param mixed $data   要返回的数据（数组/对象）
     * @param int $code     状态码
     * @param int $jsonOptions  编码选项（如JSON_UNESCAPED_UNICODE）
     * @return void     直接输出并终止脚本
     */
    public function json($data, int $code = 200, int $jsonOptions = 0): void
    {
        $this->status($code);
        $this->header('Content-Type', 'application/json; charset=utf-8');
        $this->header('Connection', "keep-alive\r\n");
        // 处理中文乱码（默认不转义Unicode）
        $jsonOptions |= JSON_UNESCAPED_UNICODE;

        echo $this->headers . json_encode($data, $jsonOptions);

        $this->send();
    }

    /**
     * 输出纯文本内容
     * @param string $content   要输出的内容
     * @param int $code         状态码（默认200）
     * @return void             直接输出并终止脚本
     */
    public function text(string $content, int $code = 200): void
    {
        $this->status($code);
        $this->header('Content-Type','text/plain; charset=utf-8');
        echo $content;
        $this->send();
        exit;
    }

    public function download(string $filePath, string $filename = null, int $code = 200): void
    {
        if(!file_exists($filePath)){
            $this->status(404)->text('文件不存在');
            return;
        }

        $filename = $filename ?? basename($filePath);
        $this->status($code);
        $this->header('Content-Type', 'application/octet-strem');
        $this->header('Content-Disposition', "attachment; filename = \"$filename\"");
        $this->header('Content-Length', filesize($filePath));
        readfile($filePath);
        $this->send();
        exit;
    }

    public function html(string $html, int $code = 200): void
    {
        $this->status($code);
        $this->header('Content-Type', 'text/html; charset=utf-8');
        echo $html;
        $this->send();
        exit;
    }

    /**
     * 标记响应已发送（防止重复操作）
     * @return void
     */
    public function send(): void
    {
        $this->sent = true;
    }

    /**
     * 检查响应是否已发送
     * @return bool
     */
    public function isSent(): bool {
        return $this->sent;
    }
}